﻿using DevExpress.XtraBars;
using DevExpress.XtraBars.Helpers;
using DevExpress.XtraEditors;
using Inaction.Business.Security;
using System.Windows.Forms;
using System.Linq;
using System;
using DevExpress.XtraTabbedMdi;
using System.Drawing;
using System.ComponentModel;
using Inaction.Rule;
using Inaction.Message;

namespace Inaction.UI.Main
{
    public partial class MainForm : XtraForm
    {
        #region 构造
        public MainForm()
        {
            InitializeComponent();

            if (DesignMode) return;

            Inaction.AppConfig.Instance.AppType = AppType.WinForm;
            MessageHost.ReceivedMessage += ReceivedMessage;
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            FormLoader.SetMainForm(this);
            DevExpress.Skins.SkinManager.EnableMdiFormSkins();
            DevExpress.Skins.SkinManager.EnableFormSkins();
            DevExpress.UserSkins.BonusSkins.Register();
            SkinHelper.InitSkinPopupMenu(barSkin);
            if (!string.IsNullOrEmpty(Properties.Settings.Default.Skin))
            {
                DevExpress.LookAndFeel.UserLookAndFeel.Default.SetStyle(Properties.Settings.Default.Style, false, true);
                DevExpress.LookAndFeel.UserLookAndFeel.Default.SetSkinStyle(Properties.Settings.Default.Skin);
                DevExpress.LookAndFeel.LookAndFeelHelper.ForceDefaultLookAndFeelChanged();
            }
            barStaticItem.Caption = string.Empty;
        }
        void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            Inaction.Util.Loger.WriteLog(e.Exception);
            MessageBox.Show(e.Exception.GetMessage(false));
        }
        #endregion

        #region 事件
        private void MainForm_Load(object sender, System.EventArgs e)
        {
            if (DesignMode) return;

            if (!string.IsNullOrEmpty(AppConfig.Instance.ApplicationName))
            {
                Text = AppConfig.Instance.ApplicationName;
            }

            if (Inaction.Security.Principal.Instance == null || !Inaction.Security.Principal.Instance.Identity.IsAuthenticated)
            {
                System.Environment.Exit(System.Environment.ExitCode);
            }
            if (Inaction.Security.Principal.Instance.Identity.IsAdmin)
            {
                bbi_MenuManage.Visibility = BarItemVisibility.Always;
            }
            else
            {
                bbi_MenuManage.Visibility = BarItemVisibility.Never;
                barManager.Items.Remove(bbi_MenuManage);
            }
            if (Inaction.AppConfig.Instance.ServiceType == ServiceType.Local)
            {
                barServer.Caption = Inaction.AppConfig.Instance.ServiceType.ToString();
            }
            else
            {
                barServer.Caption = Inaction.AppConfig.Instance.ServiceType + ":" + Inaction.AppConfig.Instance.ServerUrl;
            }

            LoadMenu();
            barUser.Caption = GetUserInfo();            
        }
        void ReceivedMessage(object obj)
        {
            if (obj is MessageInfo)
            {
                Action a = () =>
                {
                    alertControl.Show(this, new DevExpress.XtraBars.Alerter.AlertInfo("", (obj as MessageInfo).Content.ToString()));
                };
                this.Invoke(a);
            }           
        }
        private void bbi_CloseAllForm_ItemClick(object sender, ItemClickEventArgs e)
        {
            foreach (Form form in this.MdiChildren)
            {
                form.Close();
            }
        }
        private void bbi_MenuManage_ItemClick(object sender, ItemClickEventArgs e)
        {
            var f = e.Item.Tag as Form;
            if (f == null || f.IsDisposed)
            {
                e.Item.Tag = f = new MenuManage.MenuManageForm();
                FormLoader.InitForm(f);
            }
            f.Activate();
        }
        private void bbiReStart_ItemClick(object sender, ItemClickEventArgs e)
        {
            Application.Restart();
        }
        private void BarItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (e.Item.Tag == null) return;
            try
            {
                FormLoader.LoadForm(e.Item.Tag as MenuInfo);
            }
            catch (Exception)
            {
                MessageBox.Show("打开窗口出错，请求的模块可能仍在开发中，请等待!");
            }
        }
        private void bbi_ChangePassword_ItemClick(object sender, ItemClickEventArgs e)
        {
            var f = new ChangePasswordForm();
            f.TopLevel = true;
            f.ShowDialog();
        }
        private void bbiExit_ItemClick(object sender, ItemClickEventArgs e)
        {
            Close();
        }
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            Properties.Settings.Default.Style = DevExpress.LookAndFeel.UserLookAndFeel.Default.Style;
            Properties.Settings.Default.Skin = DevExpress.LookAndFeel.UserLookAndFeel.Default.SkinName;
            Properties.Settings.Default.Save();
        }
        #endregion

        #region 加载菜单
        private void LoadMenu()
        {
            var criteria = new MenuCriteria() { AppType = AppType.WinForm, ParentIdIsNull = true };
            if (!Security.Principal.Instance.Identity.IsAdmin)
            {
                criteria.IdInRoleCode = Security.Principal.Instance.GetOwnedRoles().Select(p => p.Code).ToArray();
            }
            var menus = MenuInfoList.Query(criteria);
            foreach (var menu in menus.OrderBy(p => p.OrderNo))
            {
                if (menu.SubMenus.Count == 0)
                {
                    BarButtonItem item = new BarButtonItem(barManager, menu.Name) { Tag = menu };
                    if (menu.Image != null) item.Glyph = menu.Image;
                    var link = menuBar.AddItem(item);
                    link.BeginGroup = menu.Spliter == true;
                    item.ItemClick += BarItem_ItemClick;
                }
                else
                {
                    BarSubItem item = new BarSubItem(barManager, menu.Name);
                    if (menu.Image != null) item.Glyph = menu.Image;
                    var link = menuBar.AddItem(item);
                    link.BeginGroup = menu.Spliter == true;
                    LoadSubMenu(item, menu.SubMenus);
                }
            }
        }

        private void LoadSubMenu(BarSubItem subItem, MenuInfoList subMenus)
        {
            foreach (var menu in subMenus.OrderBy(p => p.OrderNo))
            {
                if (Inaction.Security.Principal.Instance.Identity.IsAdmin || menu.MenuRoleViews.Any(p => Inaction.Security.Principal.Instance.IsInRole(p.Code)))
                {
                    if (menu.SubMenus.Count == 0)
                    {
                        BarButtonItem item = new BarButtonItem(barManager, menu.Name) { Tag = menu };
                        if (menu.Image != null) item.Glyph = menu.Image;
                        var link = subItem.AddItem(item);
                        link.BeginGroup = menu.Spliter == true;
                        item.ItemClick += BarItem_ItemClick;
                    }
                    else
                    {
                        BarSubItem item = new BarSubItem(barManager, menu.Name);
                        if (menu.Image != null) item.Glyph = menu.Image;
                        var link = subItem.AddItem(item);
                        link.BeginGroup = menu.Spliter == true;
                        LoadSubMenu(item, menu.SubMenus);
                    }
                }
            }
        }

        #endregion

        #region 方法
        protected virtual string GetUserInfo()
        {
            var str = Inaction.Security.Principal.Instance.Identity.Name;
            if (Inaction.Security.Principal.Instance.Identity.DepartmentId == null) return str;
            var departmentName = Department.Value(Department.NameProperty, Inaction.Security.Principal.Instance.Identity.DepartmentId.Value);
            if (!string.IsNullOrEmpty(departmentName))
            {
                str += "[" + departmentName + "]";
            }
            var roles = Inaction.Security.Principal.Instance.GetOwnedRoles();
            if (roles.Count() > 0)
            {
                str += "[" + string.Join(",", roles.Select(p => p.Name)) + "]";
            }
            return str;
        }
        #endregion 
    }
}
